# -*- coding: utf-8 -*-
import win32com.client
import logging
import os
from datetime import datetime,timedelta
from utils import zymysql,messager
import time


# 设置日志配置
current_dir = os.path.dirname(os.path.abspath(__file__))
target_dir = os.path.join(os.path.dirname(current_dir), "logs")  # 子目录名称
log_filename = os.path.join(target_dir, "attendance_record.log")
logging.basicConfig(
    level=logging.INFO,  # 设置日志级别为INFO
    format='%(asctime)s - %(levelname)s - %(message)s',  # 设置日志格式
    handlers=[
        logging.FileHandler(log_filename),  # 将日志写入文件
        logging.StreamHandler()  # 也打印到控制台
    ]
)

# 创建 zkemkeeper.ZKEM 对象
zkem = win32com.client.Dispatch("zkemkeeper.ZKEM")

# 设备列表，包含多个设备的IP地址和机器号
devices = [
    {"ip": "192.168.4.2", "port": 4370, "device_id": 1},
    {"ip": "192.168.0.51", "port": 4370, "device_id": 1},
    {"ip": "192.168.0.52", "port": 4370, "device_id": 2},
    {"ip": "192.168.0.53", "port": 4370, "device_id": 3},
    {"ip": "192.168.0.54", "port": 4370, "device_id": 4},
    {"ip": "192.168.0.55", "port": 4370, "device_id": 5},
    {"ip": "192.168.0.56", "port": 4370, "device_id": 6},
    {"ip": "192.168.0.57", "port": 4370, "device_id": 7}
]

#连接到考勤机
def connect_device(ip_address, port):
    try:
        max_retries = 3  # 最大重试次数
        retry_delay = 1  # 每次重试间隔（秒）

        for attempt in range(max_retries):
            if zkem.Connect_Net(ip_address, port):
                success_msg = f"成功连接考勤机 {ip_address}:{port}"
                logging.info(success_msg)
                print(success_msg)
                return True
            else:
                if attempt < max_retries - 1:  # 不是最后一次尝试
                    warning_msg = f"第 {attempt + 1} 次连接失败，{retry_delay}秒后重试... (IP: {ip_address}:{port})"
                    logging.warning(warning_msg)
                    print(warning_msg)
                    time.sleep(retry_delay)
                else:  # 最后一次尝试也失败
                    error_msg = f"同步记录连接考勤机 {ip_address}:{port} 失败（已重试 {max_retries} 次）"
                    messager.mesageuser(error_msg)
                    logging.error(error_msg)
                    return False

    except Exception as e:
        logging.error(f"连接考勤机 {ip_address}:{port} 时发生异常: {e}")
        return False

# def connect_device(ip_address, port):
#     try:
#         if zkem.Connect_Net(ip_address, port):
#             logging.info(f"成功连接考勤机 {ip_address}:{port}")
#             print(f"成功连接考勤机 {ip_address}:{port}")
#             return True
#         else:
#             msge = f"同步记录连接考勤机 {ip_address}:{port} 失败"
#             messager.mesageuser(msge)
#             logging.error(msge)
#             return False
#     except Exception as e:
#         logging.error(f"连接考勤机 {ip_address}:{port} 时发生异常: {e}")
#         return False


#----------------------------- 读取考勤记录--------------------
def read_attendance_log(device_id,ip_address):
    # today = datetime.today().date()    # 获取当天的日期
    today = (datetime.today() - timedelta(days=7)).date()
    print(today)
    try:
        attendance_records = []
        while True:
            # "192.168.0.51","192.168.0.53"
            if ip_address in ("192.168.0.52"):
                data = zkem.SSR_GetGeneralLogData(device_id)
            else:
                data = zkem.SSR_GetGeneralLogDataWithMask(device_id)
            if not data[0]:
                break
            user_id = data[1]
            time_components = data[4:10]  # 获取时间的各个部分
            try:
                dt = datetime(*time_components)
                # if dt.date() == today:
                if dt.date() == today or dt.date() > today:
                    formatted_time = dt.strftime("%Y-%m-%d %H:%M:%S")
                    attendance_records.append({'userid': user_id,'checktime': formatted_time})
            except (ValueError, TypeError) as e:
                logging.warning(f"Invalid time data for user {user_id}: {time_components}. Error: {e}")
                continue
        attempt = 0
        while attempt < 3:
            try:
                logging.info(attendance_records)
                print(attendance_records) # 也输出到控制台
                zymysql.batch_insert_attendance_records(attendance_records)
                return  # 成功后退出函数
            except Exception as e:
                attempt += 1
                logging.error(f"写入考勤记录时发生异常: {e}")
                if attempt < 3:
                    time.sleep(5)  # 等待一段时间后重试
                else:
                    logging.error("重试次数已用完，无法写入考勤记录")
                    break  # 超过最大重试次数后退出

    except Exception as e:
        logging.error(f"读取考勤记录时发生异常: {e}")


def process_device(device_info):
    """禁用设备，读取记录并启用设备"""
    try:
        # 提取设备信息
        device_id = device_info["device_id"]
        ip_address = device_info["ip"]
        port = device_info["port"]
        # 连接设备
        if not connect_device(ip_address, port):
            return
        # 禁用设备以防止数据变动
        zkem.EnableDevice(device_id, False)
        logging.info(f"设备{device_id}已禁用，开始读取考勤记录")
        # 读取考勤记录
        read_attendance_log(device_id,ip_address)

    except Exception as e:
        logging.error(f"处理设备{device_info['device_id']}时发生异常: {e}")

    finally:
        zkem.EnableDevice(device_info["device_id"], True)        # 启用设备
        logging.info(f"设备{device_info['device_id']}已启用")
        # 断开与考勤机的连接
        disconnect_device()


# 断开设备连接
def disconnect_device():
    try:
        zkem.Disconnect()
        logging.info("设备已断开连接！")
    except Exception as e:
        logging.error(f"断开连接时发生异常: {e}")


def startmain():
    try:
        for device_info in devices:
            process_device(device_info)

    except Exception as e:
        logging.error(f"程序执行过程中发生异常: {e}")


if __name__ == "__main__":
    startmain()
